package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sky.constant.MessageConstant;
import com.sky.constant.OrderStatusConstant;
import com.sky.constant.PayStatusConstant;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.service.ShoppingCartService;
import com.sky.utils.OrderNumberGenerator;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private WeChatPayUtil weChatPayUtil;

    /**
     * 用户提交订单
     * @param ordersSubmitDTO 订单提交数据
     * @return 订单提交结果
     */
    @Override
    @Transactional
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        // 1. 验证地址簿是否为空
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        // 2. 验证购物车是否为空
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.listByUserId(ordersSubmitDTO.getUserId());
        if (CollectionUtils.isEmpty(shoppingCartList)) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        // 3. 创建订单
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setNumber(OrderNumberGenerator.generateOrderNumber());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getProvinceName() + addressBook.getCityName() + 
                addressBook.getDistrictName() + addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        orders.setStatus(OrderStatusConstant.PENDING_PAYMENT);
        orders.setPayStatus(PayStatusConstant.UN_PAID);

        // 计算订单总金额
        BigDecimal totalAmount = shoppingCartList.stream()
                .map(item -> item.getAmount().multiply(new BigDecimal(item.getNumber())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        orders.setAmount(totalAmount);

        // 4. 保存订单
        orderMapper.insert(orders);

        // 5. 批量保存订单项
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(orders.getId());
            orderDetails.add(orderDetail);
        }
        orderDetailMapper.insertBatch(orderDetails);

        // 6. 清空购物车
        shoppingCartService.clean(ordersSubmitDTO.getUserId());

        // 7. 返回订单提交结果
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(orders.getId());
        orderSubmitVO.setOrderNumber(orders.getNumber());
        orderSubmitVO.setOrderAmount(orders.getAmount());
        orderSubmitVO.setOrderTime(orders.getOrderTime());

        return orderSubmitVO;
    }

    /**
     * 订单支付
     * @param orderId 订单ID
     * @return 支付必要的参数
     */
    @Override
    public OrderPaymentVO payment(Long orderId) {
        // 1. 查询订单
        Orders orders = orderMapper.getById(orderId);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 构建支付参数
        Map<String, String> payMap = new HashMap<>();
        payMap.put("appid", "wx8397f8696b538317"); // 微信小程序appid
        payMap.put("mch_id", "1497988242"); // 商户号
        payMap.put("nonce_str", OrderNumberGenerator.generateOrderNumber());
        payMap.put("body", orders.getNumber());
        payMap.put("out_trade_no", orders.getNumber());
        payMap.put("total_fee", String.valueOf(orders.getAmount().multiply(new BigDecimal(100)).intValue()));
        payMap.put("spbill_create_ip", "127.0.0.1");
        payMap.put("notify_url", "https://pay.weixin.qq.com/wxpay/pay.action");
        payMap.put("trade_type", "JSAPI");
        payMap.put("openid", "o8jXQ5H4xGAQdHjJ6q2WjR7wG6bQ"); // 用户openid，实际应从用户会话中获取

        // 3. 调用微信支付工具类，生成预支付交易会话标识
        try {
            Map<String, String> resultMap = weChatPayUtil.pay(payMap);
            // 构建返回值
            OrderPaymentVO orderPaymentVO = new OrderPaymentVO();
            orderPaymentVO.setNonceStr(resultMap.get("nonce_str"));
            orderPaymentVO.setPackageStr(resultMap.get("package"));
            orderPaymentVO.setPaySign(resultMap.get("sign"));
            orderPaymentVO.setTimeStamp(resultMap.get("timeStamp"));
            return orderPaymentVO;
        } catch (Exception e) {
            log.error("微信支付失败：{}", e.getMessage());
            throw new OrderBusinessException(MessageConstant.PAY_ORDER_FAILED);
        }
    }

    /**
     * 支付成功，修改订单状态
     * @param outTradeNo 商户订单号
     */
    @Override
    public void paySuccess(String outTradeNo) {
        // 1. 根据订单号查询订单
        Orders orders = orderMapper.getByNumber(outTradeNo);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 2. 更新订单状态
        Orders updateOrder = new Orders();
        updateOrder.setId(orders.getId());
        updateOrder.setStatus(OrderStatusConstant.TO_BE_CONFIRMED);
        updateOrder.setPayStatus(PayStatusConstant.PAID);
        updateOrder.setCheckoutTime(LocalDateTime.now());
        orderMapper.update(updateOrder);
    }

    /**
     * 用户端订单分页查询
     * @param ordersPageQueryDTO 查询条件
     * @return 分页结果
     */
    @Override
    public PageResult pageQueryUser(OrdersPageQueryDTO ordersPageQueryDTO) {
        // 调用分页查询方法
        com.github.pagehelper.PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        com.github.pagehelper.Page<OrderVO> page = orderMapper.pageQuery(ordersPageQueryDTO);
        
        // 转换为前端需要的格式
        List<OrderVO> records = page.getResult();
        for (OrderVO orderVO : records) {
            // 查询订单项
            List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderVO.getId());
            orderVO.setOrderDetailList(orderDetails);
        }
        
        return new PageResult(page.getTotal(), records);
    }

    /**
     * 管理端订单分页查询
     * @param ordersPageQueryDTO 查询条件
     * @return 分页结果
     */
    @Override
    public PageResult pageQueryAdmin(OrdersPageQueryDTO ordersPageQueryDTO) {
        // 调用分页查询方法
        com.github.pagehelper.PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        com.github.pagehelper.Page<OrderVO> page = orderMapper.pageQuery(ordersPageQueryDTO);
        
        // 转换为前端需要的格式
        List<OrderVO> records = page.getResult();
        for (OrderVO orderVO : records) {
            // 查询订单项
            List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderVO.getId());
            orderVO.setOrderDetailList(orderDetails);
        }
        
        return new PageResult(page.getTotal(), records);
    }

    /**
     * 查询订单详情
     * @param id 订单ID
     * @return 订单详情
     */
    @Override
    public OrderVO getOrderDetail(Long id) {
        // 查询订单基本信息
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 查询订单项
        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(id);

        // 构建返回值
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetails);

        return orderVO;
    }

    /**
     * 用户取消订单
     * @param id 订单ID
     */
    @Override
    @Transactional
    public void userCancelById(Long id) {
        // 查询订单
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 检查订单状态，只有待付款和待接单状态的订单可以取消
        if (orders.getStatus() > OrderStatusConstant.TO_BE_CONFIRMED) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 更新订单状态
        Orders updateOrder = new Orders();
        updateOrder.setId(orders.getId());
        updateOrder.setStatus(OrderStatusConstant.CANCELLED);
        updateOrder.setCancelTime(LocalDateTime.now());
        updateOrder.setCancelReason("用户取消");
        orderMapper.update(updateOrder);

        // 如果订单已支付，需要进行退款处理（这里简化处理，实际应调用支付接口进行退款）
        if (orders.getPayStatus() == PayStatusConstant.PAID) {
            // TODO: 调用支付接口进行退款
            log.info("订单 {} 进行退款处理", orders.getNumber());
        }
    }

    /**
     * 商家取消订单
     * @param id 订单ID
     */
    @Override
    @Transactional
    public void adminCancelById(Long id) {
        // 查询订单
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 更新订单状态
        Orders updateOrder = new Orders();
        updateOrder.setId(orders.getId());
        updateOrder.setStatus(OrderStatusConstant.CANCELLED);
        updateOrder.setCancelTime(LocalDateTime.now());
        updateOrder.setCancelReason("商家取消");
        orderMapper.update(updateOrder);

        // 如果订单已支付，需要进行退款处理
        if (orders.getPayStatus() == PayStatusConstant.PAID) {
            // TODO: 调用支付接口进行退款
            log.info("订单 {} 进行退款处理", orders.getNumber());
        }
    }

    /**
     * 接单
     * @param ordersConfirmDTO 确认接单数据
     */
    @Override
    public void confirmOrder(OrdersConfirmDTO ordersConfirmDTO) {
        Orders updateOrder = new Orders();
        updateOrder.setId(ordersConfirmDTO.getId());
        updateOrder.setStatus(OrderStatusConstant.CONFIRMED);
        orderMapper.update(updateOrder);
    }

    /**
     * 开始派送
     * @param id 订单ID
     */
    @Override
    public void startDelivery(Long id) {
        // 查询订单
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 验证订单状态
        if (orders.getStatus() != OrderStatusConstant.CONFIRMED) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 更新订单状态
        Orders updateOrder = new Orders();
        updateOrder.setId(id);
        updateOrder.setStatus(OrderStatusConstant.DELIVERY_IN_PROGRESS);
        updateOrder.setDeliveryTime(LocalDateTime.now());
        orderMapper.update(updateOrder);
    }

    /**
     * 完成派送
     * @param id 订单ID
     */
    @Override
    public void completeDelivery(Long id) {
        // 查询订单
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 验证订单状态
        if (orders.getStatus() != OrderStatusConstant.DELIVERY_IN_PROGRESS) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 更新订单状态
        Orders updateOrder = new Orders();
        updateOrder.setId(id);
        updateOrder.setStatus(OrderStatusConstant.COMPLETED);
        updateOrder.setCompletionTime(LocalDateTime.now());
        orderMapper.update(updateOrder);
    }

    /**
     * 获取订单统计数据
     * @return 订单统计信息
     */
    @Override
    public OrderStatisticsVO getStatistics() {
        OrderStatisticsVO statisticsVO = new OrderStatisticsVO();
        
        // 查询待接单数量
        statisticsVO.setToBeConfirmed(orderMapper.countByStatus(OrderStatusConstant.TO_BE_CONFIRMED));
        
        // 查询待派送数量
        statisticsVO.setConfirmed(orderMapper.countByStatus(OrderStatusConstant.CONFIRMED));
        
        // 查询派送中数量
        statisticsVO.setDeliveryInProgress(orderMapper.countByStatus(OrderStatusConstant.DELIVERY_IN_PROGRESS));
        
        return statisticsVO;
    }

    /**
     * 用户催单
     * @param id 订单ID
     */
    @Override
    public void remindOrder(Long id) {
        // 查询订单
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 验证订单状态，只有已接单状态的订单可以催单
        if (orders.getStatus() != OrderStatusConstant.CONFIRMED) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // TODO: 发送催单通知（可以通过WebSocket或消息队列实现）
        log.info("订单 {} 催单通知已发送", orders.getNumber());
    }
}